<template>
  <div class="app-container">
    <el-row :gutter="20">
      <!--部门数据-->
      <el-col :span="4" :xs="24">
        <el-card>
          <div slot="header" class="clearfix">
            <el-input v-model="deptName" placeholder="请输入部门名称" maxlength="255" clearable size="small" prefix-icon="el-icon-search" />
          </div>
          <el-tree
            ref="tree"
            class="filter-tree"
            default-expand-all
            :data="deptOptions"
            :props="defaultProps"
            :expand-on-click-node="false"
            :filter-node-method="filterNode"
            @node-click="handleNodeClick"
          />
        </el-card>
      </el-col>
      <!--用户数据-->
      <el-col :span="20" :xs="24">
        <el-card>
          <!--头部工具过滤-->
          <div v-if="showSearch" slot="header" class="clearfix">
            <el-input v-model="listQuery.username" placeholder="请输入用户名" maxlength="255" clearable size="mini" style="width: 240px;margin-right: 5px" />
            <el-input v-model="listQuery.name" placeholder="请输入姓名" maxlength="10" clearable size="mini" style="width: 240px;margin-right: 5px" />
            <el-input v-model="listQuery.phone" placeholder="请输入手机" prefix-icon="el-icon-phone" maxlength="11" clearable size="mini" style="width: 240px;margin-right: 5px" />
            <el-button type="success" size="mini" icon="el-icon-search" @click="handleFilter">搜索</el-button>
            <el-button type="warning" size="mini" icon="el-icon-refresh-left" @click="resetForm">重置</el-button>
          </div>
          <div class="opts">
            <!--左侧-->
            <el-button type="primary" icon="el-icon-plus" size="mini" @click="handleCreate">添加</el-button>
            <el-button type="success" :disabled="hasEdiObj" icon="el-icon-edit" size="mini" @click="handleUpdate(selectionChange[0])">修改</el-button>
            <el-button type="danger" :disabled="hasDelObj" icon="el-icon-delete" size="mini" @click="handleDelete">删除</el-button>
            <el-button type="warning" :disabled="hasEdiObj" icon="el-icon-refresh" size="mini" @click="resetPassword(selectionChange[0])">重置密码</el-button>
            <!--右侧-->
            <right-toolbar :show-search.sync="showSearch" :columns="columns" @queryTable="resetForm" />
          </div>
          <!--表格数据-->
          <el-table
            v-loading="loading"
            :data="tableData"
            style="width: 100%;"
            size="mini"
            element-loading-text="正在努力加载中..."
            highlight-current-row
            border
            fit
            @selection-change="handleSelectionChange"
          >
            <el-table-column type="selection" :selectable="checkboxT" width="55" />
            <el-table-column v-if="columns[0].visible" prop="username" label="用户名" />
            <el-table-column v-if="columns[1].visible" prop="name" label="用户昵称" />
            <el-table-column v-if="columns[2].visible" prop="avatarPath" width="70px" align="center" label="头像">
              <template slot-scope="scope">
                <el-avatar v-if="scope.row.avatarPath" :src="scope.row.avatarPath" />
                <el-avatar v-if="!scope.row.avatarPath"> {{ scope.row.name }} </el-avatar>
              </template>
            </el-table-column>
            <el-table-column v-if="columns[3].visible" prop="sex" label="性别">
              <template slot-scope="scope">
                {{ scope.row.sex===0?'未知':scope.row.sex===1?'男':'女' }}
              </template>
            </el-table-column>
            <el-table-column v-if="columns[4].visible" prop="phone" label="手机号" />
            <el-table-column v-if="columns[5].visible" prop="email" width="200px" label="邮箱" />
            <el-table-column v-if="columns[6].visible" prop="enabled" label="激活">
              <template slot-scope="scope">
                <el-switch v-model="scope.row.enabled" :disabled="scope.row.username===$store.getters.username" active-color="#13ce66" inactive-color="#ff4949" @change="updateEnabled({id: scope.row.id,enabled: scope.row.enabled},scope.row)" />
              </template>
            </el-table-column>
            <el-table-column v-if="columns[7].visible" prop="locked" label="锁定">
              <template slot-scope="scope">
                <el-switch v-model="scope.row.locked" :disabled="scope.row.username===$store.getters.username" active-color="#13ce66" inactive-color="#ff4949" @change="updateLocked({id: scope.row.id,locked: scope.row.locked},scope.row)" />
              </template>
            </el-table-column>
            <el-table-column v-if="columns[8].visible" prop="createdBy" label="创建人">
              <template scope="scope">
                {{ scope.row.createdUser ? scope.row.createdUser.name : '' }}
              </template>
            </el-table-column>
            <el-table-column v-if="columns[9].visible" prop="createTime" width="160px" label="创建时间" />
            <el-table-column align="center" width="130px" label="操作">
              <template slot-scope="scope">
                <el-popconfirm title="您确定要删除吗？" style="margin-right: 5px" @confirm="deleteByIds([scope.row.id])">
                  <el-button slot="reference" :disabled="scope.row.username===$store.getters.username" type="danger" icon="el-icon-delete" size="mini" />
                </el-popconfirm>
                <el-button type="primary" icon="el-icon-edit" size="mini" @click="handleUpdate(scope.row)" />
              </template>
            </el-table-column>
          </el-table>
          <!--分页-->
          <pagination v-show="total>0" :total="total" :page.sync="page.pageNum" :limit.sync="page.pageSize" @pagination="queryAll" />
        </el-card>
      </el-col>
      <!--对话框-->
      <el-dialog :title="title" :visible.sync="dialogVisible" width="45%" @open="openDialog">
        <el-row :gutter="15">
          <el-form ref="formData" :model="formData" :rules="rules" size="mini" label-width="100px">
            <el-col :span="24">
              <el-form-item label="用户名：" prop="username">
                <el-input v-model="formData.username" placeholder="请输入用户名" maxlength="255" show-word-limit clearable :style="{width: '100%'}" />
              </el-form-item>
            </el-col>
            <el-col :span="24">
              <el-form-item label="用户昵称：" prop="name">
                <el-input v-model="formData.name" placeholder="请输入用户昵称" maxlength="255" show-word-limit clearable :style="{width: '100%'}" />
              </el-form-item>
            </el-col>
            <el-col :span="24">
              <el-form-item label="电话：" prop="phone">
                <el-input v-model="formData.phone" placeholder="请输入电话" maxlength="11" show-word-limit clearable :style="{width: '100%'}" />
              </el-form-item>
            </el-col>
            <el-col :span="24">
              <el-form-item label="邮箱：" prop="email">
                <el-input v-model="formData.email" placeholder="请输入邮箱" maxlength="50" show-word-limit clearable :style="{width: '100%'}" />
              </el-form-item>
            </el-col>
            <el-col :span="8">
              <el-form-item label="性别：" prop="sex">
                <el-radio-group v-model="formData.sex" size="mini">
                  <el-radio-button :label="0">未知</el-radio-button>
                  <el-radio-button :label="1">男</el-radio-button>
                  <el-radio-button :label="2">女</el-radio-button>
                </el-radio-group>
              </el-form-item>
            </el-col>
            <el-col :span="8">
              <el-form-item label="激活：" prop="enabled">
                <el-radio-group v-model="formData.enabled" :disabled="formData.username===$store.getters.username" size="mini">
                  <el-radio-button :label="true">激活</el-radio-button>
                  <el-radio-button :label="false">禁用</el-radio-button>
                </el-radio-group>
              </el-form-item>
            </el-col>
            <el-col :span="8">
              <el-form-item label="锁定：" prop="locked">
                <el-radio-group v-model="formData.locked" :disabled="formData.username===$store.getters.username" size="mini">
                  <el-radio-button :label="true">启用</el-radio-button>
                  <el-radio-button :label="false">锁定</el-radio-button>
                </el-radio-group>
              </el-form-item>
            </el-col>
            <el-col :span="24">
              <el-form-item label="岗位：" prop="jobIds">
                <el-select v-model="formData.jobIds" multiple filterable placeholder="请选择岗位" :style="{width: '100%'}">
                  <el-option
                    v-for="item in jobOptions"
                    :key="item.value"
                    :label="item.label"
                    :value="item.value"
                    :disabled="item.disabled"
                  />
                </el-select>
              </el-form-item>
            </el-col>
            <el-col :span="24">
              <el-form-item label="部门：" prop="deptIds">
                <treeselect
                  v-model="formData.deptIds"
                  :multiple="true"
                  :show-count="true"
                  :flat="true"
                  :append-to-body="true"
                  z-index="9999"
                  search-nested
                  :options="deptOptions"
                  :normalizer="normalizer"
                  placeholder="选择部门"
                  no-children-text="当前菜单下无子部门"
                  no-results-text="查无此部门"
                />
              </el-form-item>
            </el-col>
            <el-col :span="24">
              <el-form-item label="角色：" prop="roleIds">
                <el-select v-model="formData.roleIds" multiple filterable placeholder="请选择角色" :style="{width: '100%'}">
                  <el-option
                    v-for="item in roleOptions"
                    :key="item.value"
                    :label="item.label"
                    :value="item.value"
                  />
                </el-select>
              </el-form-item>
            </el-col>
          </el-form>
        </el-row>
        <div slot="footer" class="dialog-footer">
          <el-button size="mini" @click="dialogVisible = false">
            取消
          </el-button>
          <el-button type="primary" size="mini" @click="title==='添加'?create():updateById()">
            提交
          </el-button>
        </div>
      </el-dialog>
    </el-row>
  </div>
</template>

<script>
import RightToolbar from '@/components/RightToolbar'
import { tree as deptTree } from '@/api/dept'
import { findList as roleFindList } from '@/api/role'
import { findList as jobFindList } from '@/api/job'
import { deleteByIds, findAll, updateById, create, findByDeptId, resetPassword } from '@/api/user'
import { Notification } from 'element-ui'
import Treeselect from '@riophae/vue-treeselect'
import '@riophae/vue-treeselect/dist/vue-treeselect.css'
import Pagination from '@/components/Pagination'
export default {
  name: 'Index',
  components: { Pagination, RightToolbar, Treeselect },
  data() {
    return {
      total: 0,
      page: {
        pageNum: 1,
        pageSize: 10,
        sort: '-create_time'
      },
      jobOptions: [],
      deptOptions: [],
      roleOptions: [],
      rules: {
        username: [{ required: true, message: '请输入用户名', trigger: 'blur' }],
        name: [{ required: true, message: '请输入用户昵称', trigger: 'blur' }],
        phone: [{ required: false, message: '请输入电话', trigger: 'blur' }],
        email: [{ required: false, message: '请输入邮箱', trigger: 'blur' }],
        jobIds: [{ required: true, type: 'array', message: '请选择岗位', trigger: 'change' }],
        deptIds: [{ required: true, type: 'array', message: '请选择部门', trigger: 'change' }],
        roleIds: [{ required: true, type: 'array', message: '请选择角色', trigger: 'change' }]
      },
      normalizer(node) {
        return {
          id: node.id,
          label: node.name,
          children: node.children
        }
      },
      formData: {
        id: undefined,
        name: undefined,
        username: undefined,
        avatarPath: undefined,
        avatarName: undefined,
        sex: 0,
        phone: undefined,
        email: undefined,
        enabled: true,
        locked: false,
        depts: [],
        roles: [],
        jobs: [],
        jobIds: [],
        deptIds: [],
        roleIds: []
      },
      dialogVisible: false,
      title: '添加',
      loading: false,
      selectionChange: null,
      showSearch: true,
      columns: [
        { key: 0, label: `用户名`, visible: true },
        { key: 1, label: `用户昵称`, visible: true },
        { key: 2, label: `头像`, visible: true },
        { key: 3, label: `性别`, visible: true },
        { key: 4, label: `手机号`, visible: true },
        { key: 5, label: `邮箱`, visible: true },
        { key: 6, label: `激活`, visible: true },
        { key: 7, label: `锁定`, visible: true },
        { key: 8, label: `创建人`, visible: true },
        { key: 9, label: `创建时间`, visible: true }
      ],
      tableData: [],
      deptName: null,
      hasDelObj: true,
      hasEdiObj: true,
      ids: [],
      defaultProps: {
        children: 'children',
        label: 'name'
      },
      listQuery: {
        pageNum: 1,
        pageSize: 10,
        id: undefined,
        name: undefined,
        username: undefined,
        phone: undefined
      }
    }
  },
  watch: {
    deptName(val) {
      this.$refs.tree.filter(val)
    }
  },
  created() {
    this.queryAll()
    this.findDeptAll()
  },
  methods: {
    // 部门过滤
    filterNode(value, data) {
      if (!value) return true
      return data.name.indexOf(value) !== -1
    },
    // 点击添加按钮
    handleCreate() {
      this.formData = {
        id: undefined,
        name: undefined,
        username: undefined,
        avatarPath: undefined,
        avatarName: undefined,
        sex: 0,
        phone: undefined,
        email: undefined,
        enabled: false,
        locked: false,
        jobs: [],
        depts: [],
        roles: [],
        jobIds: [],
        deptIds: [],
        roleIds: []
      }
      this.title = '添加'
      this.dialogVisible = true
      this.$nextTick(() => { this.$refs['formData'].clearValidate() })
    },
    // 打开添加/修改对话框
    openDialog() {
      setTimeout(() => {
        this.roleOptions = []
        this.$nextTick(() => { roleFindList().then(res => { this.roleOptions = res }) })
      }, 100)
      setTimeout(() => {
        this.jobOptions = []
        this.$nextTick(() => { jobFindList().then(res => { this.jobOptions = res }) })
      }, 100)
    },
    // 查询部门树
    findDeptAll() {
      this.deptOptions = []
      deptTree().then(res => { this.deptOptions = res })
    },
    // 重置用户密码
    resetPassword(row) {
      this.$confirm('您确定要重置用户密码吗?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        resetPassword(row.id).then(res => {
          Notification.success(res)
        })
      })
    },
    // 点击修改按钮
    handleUpdate(row) {
      this.formData = Object.assign({}, row) // copy obj
      this.title = '修改'
      this.dialogVisible = true
      this.$nextTick(() => { this.$refs['formData'].clearValidate() })
    },
    // 点击删除按钮
    handleDelete() {
      if (this.ids.length === 0) {
        Notification.warning('请选择要删除的菜单')
        return
      }
      this.$confirm('此操作将永久删除该记录, 是否继续?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        this.deleteByIds(this.ids)
      })
    },
    // 创建用户
    create() {
      this.$refs['formData'].validate((valid) => {
        if (!valid) return
        this.formData.jobIds.map((obj) => { this.formData.jobs.push({ id: obj }) })
        this.formData.deptIds.map((obj) => { this.formData.depts.push({ id: obj }) })
        this.formData.roleIds.map((obj) => { this.formData.roles.push({ id: obj }) })
        create(this.formData).then(res => {
          this.dialogVisible = false
          Notification.success(res)
          this.handleFilter()
        })
      })
    },
    // 更新用户
    updateById() {
      this.$refs['formData'].validate((valid) => {
        if (!valid) return
        this.formData.jobs = []
        this.formData.depts = []
        this.formData.roles = []
        this.formData.jobIds.map((obj) => { this.formData.jobs.push({ id: obj }) })
        this.formData.deptIds.map((obj) => { this.formData.depts.push({ id: obj }) })
        this.formData.roleIds.map((obj) => { this.formData.roles.push({ id: obj }) })
        updateById(this.formData).then(res => {
          this.dialogVisible = false
          Notification.success(res)
          this.handleFilter()
        })
      })
    },
    // 点击重置
    resetForm() {
      this.deptName = undefined
      this.listQuery = { pid: 0, name: undefined, username: undefined, phone: undefined }
      this.handleFilter()
    },
    checkboxT(row) {
      return row.username !== this.$store.getters.username
    },
    // 更新禁用状态
    updateEnabled(data, row) {
      updateById(data).then(res => {
        Notification.success(res)
      }).catch(err => {
        Notification.error(err)
        row.enabled = !row.enabled
      })
    },
    // 更新锁定状态
    updateLocked(data, row) {
      updateById(data).then(res => {
        Notification.success(res)
      }).catch(err => {
        Notification.error(err)
        row.enabled = !row.enabled
      })
    },
    // 删除用户
    deleteByIds(ids) {
      if (ids.length > 0) {
        deleteByIds(ids).then(res => {
          Notification.success(res)
          this.handleFilter()
        })
      }
    },
    // 查询用户
    queryAll() {
      this.loading = true
      this.tableData = []
      findAll(this.page, this.listQuery).then(res => {
        this.tableData = res.rows
        this.total = res.total
        this.tableData.forEach(item => {
          item.jobIds = []
          item.jobs.map((obj) => { item.jobIds.push(obj.id) })
          item.deptIds = []
          item.deptOptions.map((obj) => { item.deptIds.push(obj.id) })
          item.roleIds = []
          item.roles.map((obj) => { item.roleIds.push(obj.id) })
        })
        setTimeout(() => { this.loading = false }, 500)
      }).catch(() => {
        this.loading = false
      })
    },
    // 选中用户
    handleSelectionChange(val) {
      this.selectionChange = val
      this.ids.length = 0
      const _this = this
      if (val.length > 0) {
        this.hasEdiObj = val.length !== 1
        this.hasDelObj = false
      } else {
        this.hasDelObj = true
        this.hasEdiObj = true
      }
      val.forEach((element) => {
        _this.ids.push(element.id)
      })
    },
    // 节点单击事件
    handleNodeClick(data) {
      findByDeptId(data.id, this.page).then(res => {
        this.tableData = res.rows
        this.total = res.total
      })
    },
    // 重置用户信息
    handleFilter() {
      this.listQuery.pageNum = 1
      this.queryAll()
      this.findDeptAll()
    }
  }
}
</script>

<style scoped>
.opts {
  padding: 4px 0;
  display: -webkit-flex;
  display: flex;
  align-items: center;
}

.opts {
  margin-left: auto;
}
</style>
